import { Injectable, Logger, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DynamicConfigEntity } from './dynamic-config.entity';
import type { CacheInterface } from '../common/cache/cache.interface';

/**
 * 动态配置服务
 * 对应 Java: CoreConfigServiceImpl
 */
@Injectable()
export class DynamicConfigService {
  private readonly logger = new Logger(DynamicConfigService.name);
  private readonly cacheTag = 'sys_config_cache';
  private readonly cacheExpire = 3600; // 1小时

  constructor(
    @InjectRepository(DynamicConfigEntity)
    private readonly configRepository: Repository<DynamicConfigEntity>,
    @Inject('CACHE_PROVIDER')
    private readonly cache?: CacheInterface,
  ) {}

  /**
   * 获取配置项
   * @param siteId 站点ID
   * @param key 配置键
   * @returns 配置值
   */
  async getConfig(siteId: number, key: string): Promise<string | null> {
    try {
      const cacheKey = `${this.cacheTag}:${siteId}:${key}`;

      // 先从缓存获取
      let configValue: string | null = null;
      if (this.cache) {
        configValue = await this.cache.get(cacheKey);
        if (configValue) {
          return configValue;
        }
      }

      // 从数据库获取
      const config = await this.configRepository.findOne({
        where: { siteId, configKey: key },
      });

      if (config) {
        configValue = config.value;

        // 存入缓存
        if (this.cache) {
          await this.cache.set(cacheKey, configValue, this.cacheExpire);
        }

        this.logger.log(`获取配置: ${key} = ${configValue}`);
        return configValue;
      }

      this.logger.warn(`配置不存在: ${key}`);
      return null;
    } catch (error) {
      this.logger.error(`获取配置失败: ${key}`, error);
      return null;
    }
  }

  /**
   * 获取配置项（带类型转换）
   * @param siteId 站点ID
   * @param key 配置键
   * @param defaultValue 默认值
   * @returns 配置值
   */
  async getConfigValue<T = any>(
    siteId: number,
    key: string,
    defaultValue?: T,
  ): Promise<T> {
    const configValue = await this.getConfig(siteId, key);
    if (configValue === null) {
      return defaultValue as T;
    }

    try {
      // 尝试解析JSON
      if (configValue.startsWith('{') || configValue.startsWith('[')) {
        return JSON.parse(configValue);
      }

      // 尝试转换数字
      if (!isNaN(Number(configValue))) {
        return Number(configValue) as T;
      }

      // 尝试转换布尔值
      if (configValue === 'true' || configValue === 'false') {
        return (configValue === 'true') as T;
      }

      return configValue as T;
    } catch (error) {
      this.logger.warn(`配置值解析失败: ${key}`, error);
      return configValue as T;
    }
  }

  /**
   * 设置配置项
   * @param siteId 站点ID
   * @param key 配置键
   * @param value 配置值
   * @param addon 所属插件
   */
  async setConfig(
    siteId: number,
    key: string,
    value: any,
    addon: string = '',
  ): Promise<void> {
    try {
      const configValue =
        typeof value === 'string' ? value : JSON.stringify(value);

      // 检查配置是否存在
      const existingConfig = await this.configRepository.findOne({
        where: { siteId, configKey: key },
      });

      if (existingConfig) {
        // 更新配置
        existingConfig.value = configValue;
        existingConfig.updateTime = Math.floor(Date.now() / 1000);

        await this.configRepository.save(existingConfig);
      } else {
        // 创建新配置
        const newConfig = this.configRepository.create({
          siteId,
          configKey: key,
          value: configValue,
          status: 1,
          createTime: Math.floor(Date.now() / 1000),
          updateTime: Math.floor(Date.now() / 1000),
          addon: addon,
        });

        await this.configRepository.save(newConfig);
      }

      // 清除缓存
      await this.refreshConfigCache(siteId, key);

      this.logger.log(`设置配置: ${key} = ${configValue}`);
    } catch (error) {
      this.logger.error(`设置配置失败: ${key}`, error);
      throw error;
    }
  }

  /**
   * 删除配置项
   * @param siteId 站点ID
   * @param key 配置键
   */
  async deleteConfig(siteId: number, key: string): Promise<void> {
    try {
      await this.configRepository.delete({ siteId, configKey: key });

      // 清除缓存
      await this.refreshConfigCache(siteId, key);

      this.logger.log(`删除配置: ${key}`);
    } catch (error) {
      this.logger.error(`删除配置失败: ${key}`, error);
      throw error;
    }
  }

  /**
   * 获取配置分组
   * @param siteId 站点ID
   * @param group 配置分组
   * @returns 配置列表
   */
  async getConfigGroup(
    siteId: number,
    group: string,
  ): Promise<DynamicConfigEntity[]> {
    try {
      const cacheKey = `${this.cacheTag}:group:${siteId}:${group}`;

      // 先从缓存获取
      let configs: DynamicConfigEntity[] | null = null;
      if (this.cache) {
        configs = await this.cache.get(cacheKey);
        if (configs) {
          return configs;
        }
      }

      // 从数据库获取
      configs = await this.configRepository.find({
        where: { siteId, addon: group },
        order: { configKey: 'ASC' },
      });

      // 存入缓存
      if (this.cache && configs) {
        await this.cache.set(cacheKey, configs, this.cacheExpire);
      }

      return configs || [];
    } catch (error) {
      this.logger.error(`获取配置分组失败: ${group}`, error);
      return [];
    }
  }

  /**
   * 刷新配置缓存
   * @param siteId 站点ID
   * @param key 配置键（可选）
   */
  async refreshConfigCache(siteId: number, key?: string): Promise<void> {
    try {
      if (!this.cache) {
        return;
      }

      if (key) {
        // 清除单个配置缓存
        const cacheKey = `${this.cacheTag}:${siteId}:${key}`;
        await this.cache.del(cacheKey);
      } else {
        // 清除所有配置缓存
        const pattern = `${this.cacheTag}:${siteId}:*`;
        const keys = await this.cache.keys(pattern);
        if (keys.length > 0) {
          await this.cache.delMany(keys);
        }
      }

      this.logger.log(`刷新配置缓存: ${siteId}:${key || 'all'}`);
    } catch (error) {
      this.logger.error(`刷新配置缓存失败: ${siteId}:${key}`, error);
    }
  }

  /**
   * 获取配置历史版本
   * @param siteId 站点ID
   * @param key 配置键
   * @returns 版本列表
   */
  async getConfigHistory(
    siteId: number,
    key: string,
  ): Promise<DynamicConfigEntity[]> {
    try {
      return await this.configRepository.find({
        where: { siteId, configKey: key },
        order: { updateTime: 'DESC' },
      });
    } catch (error) {
      this.logger.error(`获取配置历史失败: ${key}`, error);
      return [];
    }
  }

  /**
   * 回滚配置到指定版本
   * @param siteId 站点ID
   * @param key 配置键
   * @param version 版本号
   */
  async rollbackConfig(
    siteId: number,
    key: string,
    version: number,
  ): Promise<void> {
    try {
      const historyConfig = await this.configRepository.findOne({
        where: { siteId, configKey: key },
      });

      if (!historyConfig) {
        throw new Error(`配置版本不存在: ${key}:${version}`);
      }

      // 获取当前配置
      const currentConfig = await this.configRepository.findOne({
        where: { siteId, configKey: key },
      });

      if (currentConfig) {
        // 更新当前配置
        currentConfig.value = historyConfig.value;
        currentConfig.updateTime = Math.floor(Date.now() / 1000);

        await this.configRepository.save(currentConfig);
      }

      // 清除缓存
      await this.refreshConfigCache(siteId, key);

      this.logger.log(`回滚配置: ${key} 到版本 ${version}`);
    } catch (error) {
      this.logger.error(`回滚配置失败: ${key}:${version}`, error);
      throw error;
    }
  }
}
